//
// Created by root on 19-8-6.
//

#include <cstring>
#include <dlfcn.h>
#include "AndHook.h"
#include "hook_selinux_check.h"
#include "log_utils.h"

#define TAG "SeLinux-Check"

typedef int (*func_selinux_check_access)(const char * scon,
                                const char * tcon,
                                const char *tclass,
                                const char *perm, void *aux);
static func_selinux_check_access old_selinux_check_access= nullptr;

int my_selinux_check_access(const char * scon,
                                const char * tcon,
                                const char *tclass,//service_manager
                                const char *perm/*add*/, void *aux){
    if(!old_selinux_check_access){
        LOGE("fail to get old_selinux_check_access\n");
        return 0;//ok
    }
    //LOGD("before selinux_check_access\nscon:%s tcon:%s tclass:%s perm:%s aux:%p\n",
      //      scon,tcon,tclass,perm,aux);
    if(strcmp(tclass,"service_manager")==0){
        LOGD("permit all service_manager requests\n");
        /*if(strcmp(perm,"add")==0){
            return 0;
        }*/
        return 0;
    }
    int check_ret=old_selinux_check_access(scon,tcon,tclass,perm,aux);
    LOGD("check_ret:%d\n",check_ret);
    return check_ret;
}



void hook_selinux_check_access() {
    void* selinux_check_access=dlsym(RTLD_DEFAULT,"selinux_check_access");
    if(!selinux_check_access){
        LOGE("fail to get selinux_check_access\n");
        return;
    }
    AKHookFunction(selinux_check_access, reinterpret_cast<void*>(my_selinux_check_access),
                   reinterpret_cast<void**>(&old_selinux_check_access));
    LOGD("old_selinuc_check_access:%p\n",old_selinux_check_access);
}
